package org.smartjava.concurrent.core;

import org.smartjava.util.PrintUtil;
import org.smartjava.util.ThreadUtil;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExample {


    public static void test1() throws ExecutionException, InterruptedException {
        Runnable a = () -> PrintUtil.print(ThreadUtil.threadName(), "-A-", "执行中");
        Runnable b = () -> PrintUtil.print(ThreadUtil.threadName(), "-B-", "执行中");
        Runnable c = () -> PrintUtil.print(ThreadUtil.threadName(), "-C-", "执行中");
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(a).runAfterBoth(CompletableFuture.runAsync(b), c);
        voidCompletableFuture.get();
    }

    /**
     * A执行完执行B和C，B和C都完成后执行D
     * <p>
     * A->B and C->D
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void test2() throws ExecutionException, InterruptedException {
        Runnable a = () -> PrintUtil.print(ThreadUtil.threadName(), "-A-", "执行中");
        Runnable b = () -> PrintUtil.print(ThreadUtil.threadName(), "-B-", "执行中");
        Runnable c = () -> PrintUtil.print(ThreadUtil.threadName(), "-C-", "执行中");
        Runnable d = () -> PrintUtil.print(ThreadUtil.threadName(), "-D-", "执行中");
        CompletableFuture<Void> acf = CompletableFuture.runAsync(a);
        CompletableFuture<Void> bcf = acf.thenRunAsync(b);
        CompletableFuture<Void> ccf = acf.thenRunAsync(c);
        CompletableFuture<Void> dcf = bcf.runAfterBoth(ccf, d);
        dcf.get();
    }

    /**
     * ABC先执行，都执行完再执行D
     * A、B、D -> D
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void test3() throws ExecutionException, InterruptedException {
        Runnable a = () -> PrintUtil.print(ThreadUtil.threadName(), "-A-", "执行中");
        Runnable b = () -> PrintUtil.print(ThreadUtil.threadName(), "-B-", "执行中");
        Runnable c = () -> PrintUtil.print(ThreadUtil.threadName(), "-C-", "执行中");
        Runnable d = () -> PrintUtil.print(ThreadUtil.threadName(), "-D-", "执行中");
        CompletableFuture<Void> acf = CompletableFuture.runAsync(a);
        CompletableFuture<Void> bcf = CompletableFuture.runAsync(b);
        CompletableFuture<Void> ccf = CompletableFuture.runAsync(c);
        CompletableFuture<Void> dcf = CompletableFuture.allOf(acf, bcf, ccf).thenRunAsync(d);
        dcf.get();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test3();
    }

}
